package com.example.k12.http;

import androidx.annotation.NonNull;
import com.blankj.utilcode.util.LogUtils;
import java.io.EOFException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Set;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;

public final class HttpLoggingInterceptor implements Interceptor {

    @NonNull
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        if (request.url().url().getPath().contains("/FileAttach/UploadFile")){
            return chain.proceed(request);
        }
        printUrl(request);
        printHeaders(request);
        printRequestBody(request);
        // 打印请求耗时
        long beginTime = System.currentTimeMillis();
        Response response = chain.proceed(chain.request());
        long endTime = System.currentTimeMillis();
        long spendTime = endTime - beginTime;
        LogUtils.d( "响应：" + "|此次请求耗时：" + spendTime + "ms");
        // 打印request response
        assert response.body() != null;
        MediaType mediaType = response.body().contentType();
        String content = response.body().string();
        printResponse(request, content);
        return response.newBuilder()
                .body(ResponseBody.create(mediaType, content))
                .build();
    }

    private void printUrl(Request request) {
        LogUtils.d( request.url().url().getPath());
    }

    private void printHeaders(Request request) {
        Headers headers = request.headers();
        Set<String> names = headers.names();
        StringBuilder sb = new StringBuilder();
        for (String name : names) {
            sb.append(name).append(" : ").append(headers.get(name)).append("\n");
        }
        LogUtils.d( sb.toString());
    }

    private void printRequestBody(Request request) throws IOException {
        RequestBody requestBody = request.body();
        if (null != requestBody) {
            Charset charset = StandardCharsets.UTF_8;
            MediaType contentType = requestBody.contentType();
            if (contentType != null) {
                charset = contentType.charset(charset);
            }
            Buffer buffer = new Buffer();
            requestBody.writeTo(buffer);
            if (isPlaintext(buffer)) {
                LogUtils.d( "request-->");
                if (requestBody.contentLength() < 2500) {
                    assert charset != null;
                    LogUtils.d( buffer.readString(charset));
                } else {
                    assert charset != null;
                    LogUtils.d( buffer.readString(charset));
                }
            }
        }
    }

    private void printResponse(Request request, String content) {
        String url = request.url().url().toString();
        LogUtils.d( "response-->" + url);
        // 超长的网络请求响应不用json输出，节省日志
        LogUtils.d( content);
    }

    private static boolean isPlaintext(Buffer buffer) {
        try {
            Buffer prefix = new Buffer();
            long byteCount = buffer.size() < 64 ? buffer.size() : 64;
            buffer.copyTo(prefix, 0, byteCount);
            for (int i = 0; i < 16; i++) {
                if (prefix.exhausted()) {
                    break;
                }
                int codePoint = prefix.readUtf8CodePoint();
                if (Character.isISOControl(codePoint) && !Character.isWhitespace(codePoint)) {
                    return false;
                }
            }
            return true;
        } catch (EOFException e) {
            return false;
        }
    }
}